package com.teckteam.ptvsystem.model;

/**
 * Locality class handles all geospatial data for stops and/or user-generated location
 * instances. (eg: walking origin points)
 * 
 */
public class Locality
{
   /**
    * Constructor used for direct input of values
    * 
    * @param latitude
    * @param longitude
    */
   
   private double latitude, longitude;
   private int stopCode;
   private String suburb;
   
   /**
    * Constructor given latitude/longitude values input directly.
    * 
    * @param latitude
    * @param longitude
    */
   public Locality(String suburb, double latitude, double longitude, int stopCode)
   {
      this.suburb = suburb.replaceAll("\"", "");
      this.latitude = latitude;
      this.longitude = longitude;
      this.stopCode = stopCode;
   }
   
   /**
    * Constructor taking in String latitude/longitude values.
    * 
    * @param latitude
    * @param longitude
    * @param idRead 
    */
   public Locality(String suburb, String latitude, String longitude, String stopCode)
   {
      this.suburb = suburb.replaceAll("\"", "");
      this.latitude = Double.parseDouble(latitude.replaceAll("[\"]", ""));
      this.longitude = Double.parseDouble(longitude.replaceAll("[\"]", ""));
      this.stopCode = Integer.parseInt(stopCode.replaceAll("[\"]", ""));
   }
   
   /**
    * Compare another Locality instance and returns a tangible distance in
    * metric kilometres (double floating point) using the Haversine Formula 
    * 
    * @param that
    * @return result
    */
   public double compareDistanceTo(Locality that)
   {  
      String[] dest = that.toArray();
      
      //Convert values to radians
      double sLatNum = Math.PI * latitude / 180,
             sLonNum = Math.PI * longitude / 180,
             dLatNum = Math.PI * Double.parseDouble(dest[0]) / 180,
             dLonNum = Math.PI * Double.parseDouble(dest[1]) / 180,
             theta = dLonNum - sLonNum,
             earthRadius = 6372.797,
             result = Math.acos(Math.sin(sLatNum) * Math.sin(dLatNum) +
                   Math.cos(sLatNum) * Math.cos(dLatNum) * Math.cos(theta)) * earthRadius;
      
      return result;
   }
   
   /**
    * Returns a string in format eg: "Lat:-37.222 Lon:19.4444"
    * 
    * @return String in format "Lat:-37.222 Lon:19.4444"
    */
   public String toString()
   {
      return String.format("Lat:%f Lon:%f", latitude, longitude);
   }
   
   /**
    * Returns a String array containing the latitude and longitude of the current Locality.
    * @return arr
    */
   public String[] toArray()
   {
      String[] arr = {String.format("%f", latitude), String.format("%f", longitude)};
      return arr;
   }
   
   /**
    * Returns stopCode of stop object (matched with imported and scraped data) 
    * 
    * @return stopCode
    */
   public int getStopCode()
   {
      return this.stopCode;
   }
   
   /**
    * Returns imported suburb strings of stop object
    * @return
    */
   public String getSuburb()
   {
      return this.suburb;
   }
}
